#include <sys_config.h>
#include <types.h>
#include <basic_types.h>
#include <mediatypes.h>
#include <api/libc/printf.h>
#include <api/libc/string.h>
#include <osal/osal.h>
#ifdef NEW_DEMO_FRAME
#include <api/libpub/lib_pub.h>
#include <api/libpub/lib_as.h>
#else
#include <api/libpub29/lib_pub27.h>
#include <api/libpub29/lib_as.h>
#endif
#include <hld/dis/vpo.h>

#ifdef CEC_SUPPORT
#include "cec_link.h"
#include <api/libcec/lib_cec.h>
#endif


#include <api/libosd/osd_lib.h>

#include "osdobjs_def.h"
#include "string.id"
#include "images.id"
#include "osd_config.h"

#include "menus_root.h"
#include "win_com.h"
#include "win_com_popup.h"
#include "win_com_list.h"
#include "win_signalstatus.h"

#ifdef AUTOMATIC_STANDBY
#if 1//ChengYu@20140522, support user can adjust standby time interval
#define ACTIVE_TIME                    120   //second unit  2 minute
static UINT32 ACTIVE_STANDBY_INTERVAL_TIME;
static UINT32 ACTIVE_TRIGGER_POINT;
#else
//ChengYu@20130917, set auto standby interval time to 4 hours
#define ACTIVE_STANDBY_INTERVAL_TIME   14400 //second unit  4 hour
#define ACTIVE_TIME                    120   //second unit  2 minute
#define ACTIVE_TRIGGER_POINT  (ACTIVE_STANDBY_INTERVAL_TIME - ACTIVE_TIME)
#endif

void ap_set_access_active(BOOL); 
void automatic_standby_control_active();

static UINT16 l_display_strs[3][MAX_DISP_STR_LEN]; // MUST not use display_strs[][]


/*******************************************************************************
*	WINDOW's objects declaration
*******************************************************************************/

extern CONTAINER g_win_automatic_standby;
extern TEXT_FIELD automatic_standby_txt_title;
extern TEXT_FIELD automatic_standby_count_down_time;
extern MULTI_TEXT automatic_standby_multxt;
extern TEXT_CONTENT act_standby_mtxt_content[];
static VSCR backup_vscr;  

static VACTION automatic_standby_time_keymap(POBJECT_HEAD pObj, UINT32 key);
static PRESULT automatic_standby_time_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2);

static VACTION automatic_standby_keymap(POBJECT_HEAD pObj, UINT32 key);
static PRESULT automatic_standby_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2);

//#define WIN_SH_IDX	  	WSTL_POP_WIN_01
//#define TITLE_SH_IDX	WSTL_TEXT_04
//#define SET_SH_IDX		WSTL_TEXT_04
//#define WIN_SH_IDX	  	WSTL_POP_WIN_01_8BIT //WSTL_POP_WIN_01
#define WIN_SH_IDX	  	WSTL_TEXT_04_8BIT //Martin@20150519_Auto standby
#define TITLE_SH_IDX	WSTL_POP_TEXT_8BIT //WSTL_TEXT_04_8BIT //WSTL_TEXT_04
#define SET_SH_IDX		WSTL_TEXT_04_8BIT //WSTL_TEXT_04

#ifndef SD_UI
#define W_L		8
#define W_T		95//82
#define W_W	  	270//290
#define W_H		200

#define TITLE_L		(W_L+14)//(W_L+5)
#define TITLE_T		(W_T+20)
#define TITLE_W		(W_W - 28)//(W_W - 10)
#define TITLE_H		36

#define MUL_TITLE_L	TITLE_L
#define MUL_TITLE_T	(TITLE_T+TITLE_H+2)
#define MUL_TITLE_W	TITLE_W
#define MUL_TITLE_H	76

#define	SET_L		TITLE_L
#define	SET_T		(MUL_TITLE_T + MUL_TITLE_H)
#define	SET_W		TITLE_W
#define	SET_H		36
#else
#define W_L		8
#define W_T		52
#define W_W	  	200//290
#define W_H		150

#define TITLE_L		(W_L+14)//(W_L+5)
#define TITLE_T		(W_T+20)
#define TITLE_W		(W_W - 28)//(W_W - 10)
#define TITLE_H		24

#define MUL_TITLE_L	TITLE_L
#define MUL_TITLE_T	(TITLE_T+TITLE_H+2)
#define MUL_TITLE_W	TITLE_W
#define MUL_TITLE_H	70

#define	SET_L		TITLE_L
#define	SET_T		(MUL_TITLE_T + MUL_TITLE_H)
#define	SET_W		TITLE_W
#define	SET_H		30		

#endif

#define LDEF_TITLE(root,varTxt,nxtObj,l,t,w,h,resID,str)		\
    DEF_TEXTFIELD(varTxt,&root,nxtObj,C_ATTR_ACTIVE,0, \
    0,0,0,0,0, l,t,w,h, TITLE_SH_IDX,TITLE_SH_IDX,TITLE_SH_IDX,TITLE_SH_IDX,   \
    NULL,NULL,  \
    C_ALIGN_CENTER | C_ALIGN_VCENTER, 0,0,resID,str)

#define LDEF_MTXT(root,varMtxt,nextObj,l,t,w,h,sh,cnt,content)	\
	DEF_MULTITEXT(varMtxt,&root,nextObj,C_ATTR_ACTIVE,0, \
    	0,0,0,0,0, l,t,w,h, sh,sh,sh,sh,   \
	    NULL,NULL,  \
    	C_ALIGN_CENTER|C_ALIGN_VCENTER, cnt,  0,0,w,h,NULL,content)


#define LDEF_SET(root,varTxt,nxtObj,l,t,w,h,id,str)		\
    DEF_TEXTFIELD(varTxt,&root,nxtObj,C_ATTR_ACTIVE,0, \
    id,id,id,id,id, l,t,w,h, SET_SH_IDX,SET_SH_IDX,SET_SH_IDX,SET_SH_IDX,   \
    automatic_standby_time_keymap,automatic_standby_time_callback,  \
    C_ALIGN_CENTER | C_ALIGN_VCENTER, 0,0,0,str)


#define LDEF_WIN(varCon,nxtObj,l,t,w,h,focusID)		\
    DEF_CONTAINER(varCon,NULL,NULL,C_ATTR_ACTIVE,0, \
    0,0,0,0,0, l,t,w,h, WIN_SH_IDX,WIN_SH_IDX,WIN_SH_IDX,WIN_SH_IDX,   \
    automatic_standby_keymap,automatic_standby_callback,  \
    nxtObj, focusID,0)


LDEF_TITLE(g_win_automatic_standby,automatic_standby_txt_title,&automatic_standby_multxt,\
	TITLE_L, TITLE_T, TITLE_W, TITLE_H,0,l_display_strs[0])

LDEF_MTXT(g_win_automatic_standby,automatic_standby_multxt,&automatic_standby_count_down_time, \
    MUL_TITLE_L,MUL_TITLE_T,MUL_TITLE_W,MUL_TITLE_H,SET_SH_IDX,1,act_standby_mtxt_content)

LDEF_SET(g_win_automatic_standby,automatic_standby_count_down_time,NULL, \
	SET_L, SET_T, SET_W, SET_H,1,l_display_strs[2])
	
LDEF_WIN(g_win_automatic_standby,&automatic_standby_txt_title,\
	W_L, W_T, W_W, W_H,1)



/*******************************************************************************
*	Local vriable & function declare
*******************************************************************************/
static volatile BOOL b_automatic_standby_window = FALSE;
static volatile BOOL  m_b_access = FALSE;

TEXT_CONTENT act_standby_mtxt_content[] =
{
	{STRING_UNICODE,0} //display_strs[1]
};


static VACTION automatic_standby_time_keymap(POBJECT_HEAD pObj, UINT32 key)
{
	VACTION act = VACT_PASS;
    
	return act;
}

static PRESULT automatic_standby_time_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2)
{
	PRESULT ret = PROC_PASS;

	switch(event)
	{
	case EVN_PRE_DRAW:
		break;
	case EVN_UNKNOWN_ACTION:
		break;
	}
    
	return ret;
}

static VACTION automatic_standby_keymap(POBJECT_HEAD pObj, UINT32 key)
{
	VACTION act = VACT_PASS;
	switch(key)
	{
	case V_KEY_EXIT:
		act = VACT_CLOSE;		
		break;
	}
	return act;
}

static PRESULT automatic_standby_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2)
{
	PRESULT ret = PROC_PASS;
    INT32  time;
    BYTE    array[60];
    UINT32 hkey;
    TEXT_CONTENT *ptxt_cntnt; 
    //libc_printf( "typde:%d\n",event);
    switch(event)
	{
	case EVN_PRE_OPEN:
        osal_task_dispatch_off();
        b_automatic_standby_window = TRUE;
        osal_task_dispatch_on();
        wincom_backup_region(&pObj->frame,&backup_vscr);
        time = param2 & 0x00FFFFFF;
        time = ACTIVE_STANDBY_INTERVAL_TIME - time;
        sprintf(array,"%02d:%02d",time/60,time%60);
        OSD_SetTextFieldContent(&automatic_standby_count_down_time,STRING_ANSI,(UINT32)array);
        MEMSET(array,0x00,sizeof(array));
        STRCPY(array,"Standby Time");
        OSD_SetTextFieldContent(&automatic_standby_txt_title,STRING_ANSI,(UINT32)array);
        ptxt_cntnt = &act_standby_mtxt_content[0];
        ptxt_cntnt->text.pString = l_display_strs[1];
        STRCPY(array,"Count down,Press any key to exit");
        ComAscStr2Uni(array,ptxt_cntnt->text.pString);
        break;
	case EVN_POST_OPEN:
		break;
	case EVN_PRE_CLOSE:
		break;
	case EVN_POST_CLOSE:
        wincom_restore_region(&backup_vscr);
        osal_task_dispatch_off();
        b_automatic_standby_window = FALSE;
        osal_task_dispatch_on();
        //ret = PROC_LEAVE;
		break;
    case EVN_MSG_GOT:
        if(param1 == CTRL_MSG_SUBTYPE_STATUS_AUTOMATIC_STANDBY_TIME)
        {
             time = param2 & 0x00FFFFFF;
             time = ACTIVE_STANDBY_INTERVAL_TIME - time;
             sprintf(array,"%02d:%02d",time/60,time%60);
             OSD_SetTextFieldContent(&automatic_standby_count_down_time,STRING_ANSI,(UINT32)array);
             OSD_TrackObject((POBJECT_HEAD)&automatic_standby_count_down_time,C_UPDATE_ALL);
             if(time <= 0)
             {
                 ap_vk_to_hk(0,V_KEY_POWER,&hkey);
                 ret = PROC_LEAVE;
                 ap_send_msg(CTRL_MSG_SUBTYPE_KEY, hkey, FALSE);
             }
        }
        break;
    case EVN_KEY_GOT:
         ret = PROC_LEAVE;
        break;
	}

	return ret;
}

BOOL get_automatic_windows_state(void)
{
    return b_automatic_standby_window;
}

void automatic_standy_message_proc(UINT32 msg_type,UINT32 msg_code)
{
    INT32 msg_sub_type;
    INT32 msg_sub_code;

    msg_sub_code = msg_code&0x00FFFFFF;
    if(msg_sub_code < ACTIVE_TRIGGER_POINT && ((msg_code>>24) == V_KEY_EXIT))
    {
        OSD_ObjClose((POBJECT_HEAD)&g_win_automatic_standby,C_CLOSE_CLRBACK_FLG);
       // menu_stack_pop();
    }
    else
    {
        if(!get_automatic_windows_state())
        {
            OSD_ObjOpen((POBJECT_HEAD)&g_win_automatic_standby,msg_sub_code);
           // menu_stack_push((POBJECT_HEAD)&g_win_automatic_standby);
        }
        else
        {
            OSD_ObjProc((POBJECT_HEAD)&g_win_automatic_standby,(MSG_TYPE_MSG<<16)|msg_type,msg_sub_code,msg_sub_code);
        }
    }
}

BOOL ap_get_access_active(void)
{
    return m_b_access;
}
void ap_set_access_active(BOOL state)
{
    m_b_access = state;
}
void  automatic_standby_loop(void)
{
    static INT32 cur_time = 0,old_time = 0;
    UINT32 vkey;
    INT32  count;
    INT32  msg_code;
    SYSTEM_DATA *sys_data;
    static INT32 cur_time_1 = 0;
    
    sys_data = sys_data_get();

    if(sys_data->auto_standby_en == 0)
        return;

#if 1//ChengYu@20140522, support user can adjust standby time interval
	if(api_pvr_is_record_active())
		return;
#endif

    if(old_time == 0 && old_time == cur_time )
    {   
        cur_time = osal_get_time();
        old_time = cur_time;
    }
    else
        cur_time = osal_get_time();
    if(ap_get_access_active())
    {
#if 1//ChengYu@20140522, support user can adjust standby time interval
    /*Martin@20150311_Auto_Standby*/
    switch(sys_data->auto_standby_en)
	{
	case 1:
		ACTIVE_STANDBY_INTERVAL_TIME = 3600; //1hr = 3600s
		break;
	case 2:
		ACTIVE_STANDBY_INTERVAL_TIME = 3600 * 2; //2hr = 7200s
		break;
	case 3:
		ACTIVE_STANDBY_INTERVAL_TIME = 3600 * 4; //4hr = 14400s
		break;
	case 4:
		ACTIVE_STANDBY_INTERVAL_TIME = 3600 * 8; //8hr
		break;
	case 5:
		ACTIVE_STANDBY_INTERVAL_TIME = 3600 * 12; //12hr
		break;
	default:
		break;
	}
   	//ACTIVE_STANDBY_INTERVAL_TIME = sys_data->auto_standby_en * 14400;//unit 4hr
    //----End Martin
    ACTIVE_TRIGGER_POINT = ACTIVE_STANDBY_INTERVAL_TIME - ACTIVE_TIME;
#endif
        ap_set_access_active(FALSE);
        old_time = cur_time;
    }
    count = cur_time - old_time; 
    if(count >= ACTIVE_TRIGGER_POINT)
    {
        if(cur_time - cur_time_1 >= 1)
        {
            ap_send_msg(CTRL_MSG_SUBTYPE_STATUS_AUTOMATIC_STANDBY_TIME,count,FALSE);
            if(ACTIVE_STANDBY_INTERVAL_TIME - count <= 0)
            {
#ifdef CEC_SUPPORT                                                        //Seiya Add,Fix BUG37993.Autmatic standby cause 
		CEC_Link_Power_Off_by_Local_User();
                 osal_task_sleep(100);
#endif 
                while(get_automatic_windows_state())
                {    
                    osal_task_sleep(10);
                }                               
                 //power_switch(0);
                ap_set_access_active(TRUE); 
            }
            
        }
    }
    else 
    {
        if(get_automatic_windows_state())
        {
            ap_send_msg(CTRL_MSG_SUBTYPE_STATUS_AUTOMATIC_STANDBY_TIME,count|(V_KEY_EXIT<<24),FALSE);
            while(get_automatic_windows_state())
            {    
                osal_task_sleep(10);
            }           
        }
    }
    cur_time_1 = cur_time;
}

#endif

